package com.greateamd.timetableasy.client.mvc.view.crud.event;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.greateamd.timetableasy.client.domain.EventType;
import com.greateamd.timetableasy.client.mvc.model.Model;
import com.greateamd.timetableasy.client.services.campus.CampusService;
import com.greateamd.timetableasy.client.services.campus.CampusServiceAsync;
import com.greateamd.timetableasy.client.services.cursus.CursusService;
import com.greateamd.timetableasy.client.services.cursus.CursusServiceAsync;
import com.greateamd.timetableasy.client.services.promotion.PromotionService;
import com.greateamd.timetableasy.client.services.promotion.PromotionServiceAsync;
import com.greateamd.timetableasy.client.services.university.UniversityService;
import com.greateamd.timetableasy.client.services.university.UniversityServiceAsync;
import com.greateamd.timetableasy.client.services.user.UserService;
import com.greateamd.timetableasy.client.services.user.UserServiceAsync;
import com.greateamd.timetableasy.client.services.util.ServerCall;
import com.greateamd.timetableasy.client.widgets.EntityContainer;
import com.greateamd.timetableasy.client.widgets.MessagePopupPanel;
import com.greateamd.timetableasy.client.widgets.campus.CampusListBox;
import com.greateamd.timetableasy.client.widgets.campus.PromotionOfCampusManagerListBox;
import com.greateamd.timetableasy.client.widgets.cursus.CursusListBox;
import com.greateamd.timetableasy.client.widgets.event.EventPanel;
import com.greateamd.timetableasy.client.widgets.university.UniversityListBox;
import com.greateamd.timetableasy.domain.Campus;
import com.greateamd.timetableasy.domain.Event;
import com.greateamd.timetableasy.domain.Promotion;
import com.greateamd.timetableasy.domain.StudyPeriod;
import com.greateamd.timetableasy.domain.User;

public class AddEventPage <M extends Model> extends IAddEventPage<M>{

	@UiTemplate("AddEventPage.ui.xml")
	interface AddEventPageUIBinder extends UiBinder<Widget, AddEventPage> {}
	private static AddEventPageUIBinder uiBinder = GWT.create(AddEventPageUIBinder.class);
	
	//Event
	@UiField EventPanel eventPanel;
	@UiField Button submitBt;
	//Campus
	@UiField CampusListBox listAllCampus;
	//promotion
	@UiField PromotionOfCampusManagerListBox listAllPromotions;
	//Study period
	@UiField CursusListBox listOfCursusAvailable;
	@UiField EntityContainer<StudyPeriod> listOfSp;
	@UiField Button addSpBt;
	//University
	@UiField UniversityListBox listAllUniversities;

	private StudyPeriod toAddSp;
	private EventType typeRestriction;
	private User toAddUser;
	
/**
	 * Constructor
	 */
	public AddEventPage(M model,final EventType typeRestriction) {
	    initWidget(uiBinder.createAndBindUi(this));
	    this.typeRestriction = typeRestriction;
	    eventPanel.setEventTypeRestriction(typeRestriction);
	    toAddUser = model.getUser();
	    switch(typeRestriction){
	    	case CAMPUS :
	    		listAllCampus.setVisible(true);
	    		listAllCampus.loadCampus();
	    		break;
	    	
	    	case PROMOTION:
	    		listAllPromotions.setVisible(true);
	    		listAllPromotions.loadPromotion();
	    		break;
	    
	    	case STUDY_PERIOD:
	    		listOfCursusAvailable.setVisible(true);
	    		listOfSp.setVisible(true);
	    		addSpBt.setVisible(true);
	    		break;
	    	case UNIVERSITY:
	    		listAllUniversities.setVisible(true);
	    		listAllUniversities.loadUniversities();
	    		break;
	    }
	}

	public Widget getWidgetPage() {
		return this;
	}

	@Override
	public void setUser(User user) {
	}


	//---------------------------------------------------------------------
	//-------------------------- UI action

	
	//---------------------------------------------------------------------
	//-------------------------- Handler
	@UiHandler("submitBt")
	void onSubmitBtClick(ClickEvent e){
		addEvent();
	}
	
	@UiHandler("listOfCursusAvailable")
	void onCursusChange(ChangeEvent e){
		if(listOfCursusAvailable.getSelectedCursus() != null){
			listOfSp.clear();
			for(StudyPeriod sp : listOfCursusAvailable.getSelectedCursus().getStudyPeriods()){
				listOfSp.addEntity(sp);
			}
		}
	}
	
	@UiHandler("addSpBt")
	void onAddSpBtClick(ClickEvent e){
		if(listOfSp.getSelectedEntity() != null){
			toAddSp = listOfSp.getSelectedEntity();
		} else {
			Window.alert("You must select a Study period");
		}
	}
	
	//---------------------------------------------------------------------
	//-------------------------- Server call
	
	private void addEvent() {
		if(!checkFormValidity()){
			Window.alert("Invalid form, you must valid and apply your form");
			return;
		}
		new ServerCall<Boolean>() {

			@Override
			protected void callService(AsyncCallback<Boolean> asyncCallback) {
				Event e = eventPanel.getEvent();
				 switch(typeRestriction){
				 
				 	case USER :
						final UserServiceAsync userService = GWT.create(UserService.class);
						userService.addEvent(e,asyncCallback);
						break;
						
			    	case CAMPUS :
			    		final CampusServiceAsync campusService = GWT.create(CampusService.class);
						Campus c = listAllCampus.getSelectedCampus();
						c.addEvent(e);
						campusService.update(c, asyncCallback);
						break;
			    	
			    	case PROMOTION:
			    		final PromotionServiceAsync promotionService = GWT.create(PromotionService.class);
			    		Promotion p = listAllPromotions.getSelectedPromotion();
			    		p.addEvent(e);
			    		promotionService.update(p, asyncCallback);
		    			break;
			    	
			    	case UNIVERSITY :
						final UniversityServiceAsync universityService = GWT.create(UniversityService.class);
						listAllUniversities.getSelectedUniversity().addEvent(e);
						universityService.update(listAllUniversities.getSelectedUniversity(), asyncCallback);
						break;
					
			    	case STUDY_PERIOD:
			    		if(toAddSp == null){
			    			Window.alert("You must choose a study period");
			    			return;
			    		}
			    		final CursusServiceAsync cursusService = GWT.create(CursusService.class);
			    		toAddSp.addEvent(e);
			    		cursusService.updateSp(toAddSp, asyncCallback);
			    		break;
				}
				
			}

			@Override
			public void onSuccess(Boolean success) {
				if(success)
					new MessagePopupPanel("Success","Event has well been added").show();
				else
					new MessagePopupPanel("Error","Operation failed").show();
			}
		}.call();
	}

	private boolean checkFormValidity() {
		if(eventPanel.getEvent()==null) return false;
		if(!eventPanel.eventPanelIsValid()) return false;
		return true;
	}
}

